using System;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;
using System.Linq;
using System.Windows.Forms;

namespace HslControls
{
	/// <summary>
	/// 饼图的控件
	/// </summary>
	[Description("饼图控件，支持设置颜色，是否显示百分比功能")]
	public class HslPieChart : UserControl
	{
		private Color percentColor = Color.DodgerBlue;

		private Brush percentBrush = new SolidBrush(Color.DodgerBlue);

		private HslPieItem[] pieItems = new HslPieItem[0];

		private Random random = null;

		private StringFormat formatCenter = null;

		private int margin = 50;

		private bool m_IsRenderPercent = false;

		private bool m_IsRenderSmall = true;

		private string percenFormat = "{0:F2}%";

		/// <summary> 
		/// 必需的设计器变量。
		/// </summary>
		private IContainer components = null;

		/// <summary>
		/// 是否显示百分比信息
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[DefaultValue(false)]
		[Description("获取或设置是否显示百分比占用")]
		public bool IsRenderPercent
		{
			get
			{
				return m_IsRenderPercent;
			}
			set
			{
				m_IsRenderPercent = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 是否在图形上显示占比非常小的文本信息
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置是否显示占比很小的文本信息")]
		[DefaultValue(true)]
		public bool IsRenderSmall
		{
			get
			{
				return m_IsRenderSmall;
			}
			set
			{
				m_IsRenderSmall = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置文本距离，单位为像素，默认40
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置文本距离，单位为像素，默认50")]
		[DefaultValue(50)]
		public int TextMargin
		{
			get
			{
				return margin;
			}
			set
			{
				margin = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置文百分比文字的颜色信息
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置文百分比文字的颜色信息")]
		[DefaultValue(typeof(Color), "DodgerBlue")]
		public Color PercentColor
		{
			get
			{
				return percentColor;
			}
			set
			{
				percentColor = value;
				percentBrush.Dispose();
				percentBrush = new SolidBrush(percentColor);
				Invalidate();
			}
		}

		/// <summary>
		/// 获取或设置文百分比文字的格式化信息
		/// </summary>
		[Browsable(true)]
		[Category("HslControls")]
		[Description("获取或设置文百分比文字的格式化信息")]
		[DefaultValue("{0:F2}%")]
		public string PercentFormat
		{
			get
			{
				return percenFormat;
			}
			set
			{
				percenFormat = value;
				Invalidate();
			}
		}

		/// <summary>
		/// 实例化一个饼图的控件
		/// </summary>
		public HslPieChart()
		{
			InitializeComponent();
			random = new Random();
			formatCenter = new StringFormat();
			formatCenter.Alignment = StringAlignment.Center;
			formatCenter.LineAlignment = StringAlignment.Center;
			SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, value: true);
			SetStyle(ControlStyles.ResizeRedraw, value: true);
			SetStyle(ControlStyles.OptimizedDoubleBuffer, value: true);
			SetStyle(ControlStyles.AllPaintingInWmPaint, value: true);
			pieItems = new HslPieItem[0];
			if (GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
			{
				pieItems = new HslPieItem[5]
				{
					new HslPieItem
					{
						Name = "数据一",
						Value = 30,
						PieColor = Color.DodgerBlue
					},
					new HslPieItem
					{
						Name = "数据二",
						Value = 10,
						PieColor = Color.Purple
					},
					new HslPieItem
					{
						Name = "数据三",
						Value = 16,
						PieColor = Color.Tomato
					},
					new HslPieItem
					{
						Name = "数据四",
						Value = 15,
						PieColor = Color.Orange
					},
					new HslPieItem
					{
						PieColor = Color.Wheat,
						Name = "数据五",
						Value = 12
					}
				};
			}
		}

		private void SetMarginPaint(int value)
		{
			if (value > 500)
			{
				margin = 80;
			}
			else if (value > 300)
			{
				margin = 60;
			}
			else
			{
				margin = 40;
			}
		}

		private Point GetCenterPoint(out int width)
		{
			if (base.Width > base.Height)
			{
				width = base.Height / 2 - margin - 8;
				return new Point(base.Height / 2 - 1, base.Height / 2 - 1);
			}
			width = base.Width / 2 - margin - 8;
			return new Point(base.Width / 2 - 1, base.Width / 2 - 1);
		}

		/// <summary>
		/// 随机生成颜色，该颜色相对于白色为深色颜色
		/// </summary>
		/// <returns></returns>
		private Color GetRandomColor()
		{
			int int_Red = random.Next(256);
			int int_Green = random.Next(256);
			int int_Blue = (int_Red + int_Green > 430) ? random.Next(100) : random.Next(200);
			return Color.FromArgb(int_Red, int_Green, int_Blue);
		}

		/// <summary>
		/// 重新绘制控件的外观
		/// </summary>
		/// <param name="e">事件</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			if (!Authorization.iashdiadasbdnajsdhjaf())
			{
				return;
			}
			e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
			e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
			int width;
			Point center = GetCenterPoint(out width);
			Rectangle rect_center = new Rectangle(center.X - width, center.Y - width, width + width, width + width);
			if (width > 0 && pieItems.Length != 0)
			{
				e.Graphics.FillEllipse(Brushes.AliceBlue, rect_center);
				e.Graphics.DrawEllipse(Pens.DodgerBlue, rect_center);
				Rectangle rect_tran = new Rectangle(rect_center.X - center.X, rect_center.Y - center.Y, rect_center.Width, rect_center.Height);
				e.Graphics.TranslateTransform(center.X, center.Y);
				e.Graphics.RotateTransform(90f);
				e.Graphics.DrawLine(Pens.DimGray, 0, 0, width, 0);
				int totle = pieItems.Sum((HslPieItem item) => item.Value);
				float totleAngle = 0f;
				float lastAngle = -90f;
				for (int i = 0; i < pieItems.Length; i++)
				{
					Pen piePen = new Pen(pieItems[i].LineColor, 1f);
					SolidBrush pieBrush = new SolidBrush(pieItems[i].PieColor);
					SolidBrush fontBrush = new SolidBrush(pieItems[i].FontColor);
					float textWidth = e.Graphics.MeasureString(pieItems[i].Name, Font).Width + 3f;
					float single = 0f;
					single = ((totle != 0) ? Convert.ToSingle((double)pieItems[i].Value * 1.0 / (double)totle * 360.0) : ((float)(360 / pieItems.Length)));
					e.Graphics.FillPie(pieBrush, rect_tran, 0f, 0f - single);
					e.Graphics.RotateTransform(0f - single / 2f);
					if (single < 2f && !IsRenderSmall)
					{
						totleAngle += single;
					}
					else
					{
						totleAngle += single / 2f;
						int mark = 15;
						if (totleAngle < 45f || totleAngle > 315f)
						{
							mark = 20;
						}
						if (totleAngle > 135f && totleAngle < 225f)
						{
							mark = 20;
						}
						e.Graphics.DrawLine(piePen, width * 2 / 3, 0, width + mark, 0);
						e.Graphics.TranslateTransform(width + mark, 0f);
						if (totleAngle - lastAngle < 5f)
						{
						}
						lastAngle = totleAngle;
						if (totleAngle < 180f)
						{
							e.Graphics.RotateTransform(totleAngle - 90f);
							e.Graphics.DrawLine(piePen, 0f, 0f, textWidth, 0f);
							e.Graphics.DrawString(pieItems[i].Name, Font, fontBrush, new Point(0, -Font.Height));
							if (IsRenderPercent)
							{
								e.Graphics.DrawString(string.Format(percenFormat, single * 100f / 360f), Font, percentBrush, new Point(0, 1));
							}
							e.Graphics.RotateTransform(90f - totleAngle);
						}
						else
						{
							e.Graphics.RotateTransform(totleAngle - 270f);
							e.Graphics.DrawLine(piePen, 0f, 0f, textWidth, 0f);
							e.Graphics.TranslateTransform(textWidth - 3f, 0f);
							e.Graphics.RotateTransform(180f);
							e.Graphics.DrawString(pieItems[i].Name, Font, fontBrush, new Point(0, -Font.Height));
							if (IsRenderPercent)
							{
								e.Graphics.DrawString(string.Format(percenFormat, single * 100f / 360f), Font, percentBrush, new Point(0, 1));
							}
							e.Graphics.RotateTransform(-180f);
							e.Graphics.TranslateTransform(0f - textWidth + 3f, 0f);
							e.Graphics.RotateTransform(270f - totleAngle);
						}
						e.Graphics.TranslateTransform(-width - mark, 0f);
						e.Graphics.RotateTransform(0f - single / 2f);
						totleAngle += single / 2f;
					}
					pieBrush.Dispose();
					piePen.Dispose();
					fontBrush.Dispose();
				}
				e.Graphics.ResetTransform();
			}
			else
			{
				e.Graphics.FillEllipse(Brushes.AliceBlue, rect_center);
				e.Graphics.DrawEllipse(Pens.DodgerBlue, rect_center);
				e.Graphics.DrawString("空", Font, Brushes.DimGray, rect_center, formatCenter);
			}
			base.OnPaint(e);
		}

		/// <summary>
		/// 设置显示的数据源
		/// </summary>
		/// <param name="source">特殊的显示对象</param>
		/// <exception cref="T:System.ArgumentNullException"></exception>
		public void SetDataSource(HslPieItem[] source)
		{
			if (source != null)
			{
				pieItems = source;
				Invalidate();
			}
		}

		/// <summary>
		/// 根据名称和值进行数据源的显示，两者的长度需要一致
		/// </summary>
		/// <param name="names">名称</param>
		/// <param name="values">值</param>
		/// <exception cref="T:System.ArgumentNullException"></exception>
		public void SetDataSource(string[] names, int[] values)
		{
			if (names == null)
			{
				throw new ArgumentNullException("names");
			}
			if (values == null)
			{
				throw new ArgumentNullException("values");
			}
			if (names.Length != values.Length)
			{
				throw new Exception("两个数组的长度不一致！");
			}
			pieItems = new HslPieItem[names.Length];
			for (int i = 0; i < names.Length; i++)
			{
				pieItems[i] = new HslPieItem
				{
					Name = names[i],
					Value = values[i],
					PieColor = GetRandomColor()
				};
			}
			Invalidate();
		}

		/// <summary> 
		/// 清理所有正在使用的资源。
		/// </summary>
		/// <param name="disposing">如果应释放托管资源，为 true；否则为 false。</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing && components != null)
			{
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		/// <summary> 
		/// 设计器支持所需的方法 - 不要修改
		/// 使用代码编辑器修改此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			SuspendLayout();
			base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
			BackColor = System.Drawing.Color.Transparent;
			base.Name = "HslPieChart";
			ResumeLayout(false);
		}
	}
}
